/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.yonsei.iwb.smarttv.userpreference;

import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.NodeIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.vocabulary.RDF;
import edu.yonsei.iwb.smarttv.querygraph.OntologySearchbySPARQL;
import edu.yonsei.iwb.smarttv.result.SearchResultSet;
import java.util.ArrayList;
import java.util.Vector;



/**
 * 사용자 선호 리소스 정보를 얻기 위한 SPARQL 집합
 *
 * @author JDK 
 */
public class ExtendedResources {

    private Model tvModel;
    private OntologySearchbySPARQL oss;
    private static final int TV_PREFERENCE_FACTOR_SIZE = 4;
    private static final int FILM_PREFERENCE_FACTOR_SIZE = 3;
    private static final int MV_PREFERENCE_FACTOR_SIZE = 2;
    private String tvQueryGenre = "SELECT  ?x0 ?y\n" +
                            "WHERE\n" +
                            "  { <media>\n" +
                            "              <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvEpisode> .\n" +
                            "    ?x0       <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvGenre> .\n" +
                            "    ?y        <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvProgram> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program__episodes>  <media> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program__genre>  ?x0 .\n" +
                            "  }";
    private String tvQueryTvActor = "SELECT  ?x1\n" +
                            "WHERE\n" +
                            "  { <media>\n" +
                            "              <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvEpisode> .\n" +
                            "    ?y        <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvProgram> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program__episodes>  <media> .\n" +
                            "    ?x1       <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvActor> .\n" +
                            "    ?z        <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvRegularPerformance> .\n" +
                            "    ?y        <http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program__regular_cast>  ?z .\n" +
                            "    ?z        <http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/regular_tv_appearance__actor>  ?x1 .\n" +
                            "  }";
    private String tvQueryTvWriter = "SELECT  ?x2\n" +
                            "WHERE\n" +
                            "  { <media>\n" +
                            "              <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvEpisode> .\n" +
                            "    ?y        <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvProgram> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program__episodes>  <media> .\n" +
                            "    ?x2       <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvWriter> .\n" +
                            "    ?a        <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvProgram-writerRelationship> .\n" +
                            "    ?y        <http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program__recurring_writers>  ?a .\n" +
                            "    ?a        <http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program_writer_relationship__writer>  ?x2 .\n" +
                            "  }";
    private String tvQueryTvNetwork = "SELECT  ?x3\n" +
                            "WHERE\n" +
                            "  { <media>\n" +
                            "              <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvEpisode> .\n" +
                            "    ?y        <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvProgram> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program__episodes>  <media> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program__original_network>  ?c .\n" +
                            "    ?x3        <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvNetwork> .\n" +
                            "    ?c        <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/TvProgramDurationAtNetwork> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_network_duration__network>  ?x3 .\n" +
                            "  }";
    private String filmQueryFilmGenre = "SELECT  ?x0 ?x1 ?x2\n" +
                            "WHERE\n" +
                            "  { ?x0       <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/FilmGenre> .\n" +
                            "    <media>\n" +
                            "              <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/Film> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/film/film__genre>  ?x0.\n" +
                            "  }";
    private String filmQueryFilmActor = "SELECT  ?x1\n" +
                            "WHERE\n" +
                            "  { ?y        <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/FilmPerformance> .\n" +
                            "    ?x1       <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/FilmActor> .\n" +
                            "    <media>\n" +
                            "              <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/Film> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/film/film__starring>  ?y .\n" +
                            "    ?y        <http://iweb.yonsei.ac.kr/ontologies/smarttv/film/performance__actor>  ?x1 .\n" +
                            "  }";
    private String filmQueryFilmDirector = "SELECT  ?x2\n" +
                            "WHERE\n" +
                            "  { ?x2       <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/FilmDirector> .\n" +
                            "    <media>\n" +
                            "              <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/Film> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/film/film__directed_by>  ?x2 .\n" +
                            "  }";
    private String mvQueryArtist = "SELECT  ?x0\n" +
                            "WHERE\n" +
                            "  { ?x0       <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/MusicalArtist> .\n" +
                            "    <media>\n" +
                            "              <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/MusicVideo> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/music/music_video__artist>  ?x0 .\n" +
                            "  }";
    private String mvQueryComposer = "SELECT  ?x1\n" +
                            "WHERE\n" +
                            "  { ?y        <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/Composition> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/music/composition__composer>  ?x1 .\n" +
                            "    <media>\n" +
                            "              <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/MusicVideo> ;\n" +
                            "              <http://iweb.yonsei.ac.kr/ontologies/smarttv/music/music_video__compositions>  ?y .\n" +
                            "    ?x1       <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>  <http://iweb.yonsei.ac.kr/ontologies/smarttv/Composer> .\n" +
                            "  }";
    
    private String tvGenre = "http://iweb.yonsei.ac.kr/ontologies/smarttv/TvGenre";
    private String tvProgram = "http://iweb.yonsei.ac.kr/ontologies/smarttv/TvProgram";
    private String tvActor = "http://iweb.yonsei.ac.kr/ontologies/smarttv/TvActor";
    private String tvRegularPerformance = "http://iweb.yonsei.ac.kr/ontologies/smarttv/TvRegularPerformance";
    private String tvWriter = "http://iweb.yonsei.ac.kr/ontologies/smarttv/TvWriter";
    private String tvProgram_Writer_Relationship = "http://iweb.yonsei.ac.kr/ontologies/smarttv/TvProgram-writerRelationship";
    //영화 리소스 
    private String getFilmGenre = "http://iweb.yonsei.ac.kr/ontologies/smarttv/film/film__genre"; //영화장르
    private String getFilmStarring = "http://iweb.yonsei.ac.kr/ontologies/smarttv/film/film__starring"; //영화출연배우
    private String getFilmWrittenBy = "http://iweb.yonsei.ac.kr/ontologies/smarttv/film/film__written_by"; //영화원작자
    //TV 에피소드 리소스 
    private String getTvGenre = "http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program__genre"; //TV 장르
    private String hasTvEpisodes = "http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program__episodes"; //TV 출연배우1
    private String getTv_Program_regular_cast = "http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program__regular_cast"; //TV 출연배우2
    private String getRegulaer_Tv_Appearance_Actor = "http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/regular_tv_appearance__actor"; //TV 출연배우3
    private String hasTv_Program_Recurring_Writer = "http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program__recurring_writers";//방송작가
    private String hasTv_Program_Writer = "http://iweb.yonsei.ac.kr/ontologies/smarttv/tv/tv_program_writer_relationship__writer";//방송작가2
    //뮤직비디오
    private String hasMusic_Video_Artist = "http://iweb.yonsei.ac.kr/ontologies/smarttv/music/music_video__artist";// 가수 
    private String hasCompositionComposer = "http://iweb.yonsei.ac.kr/ontologies/smarttv/music/composition__composer";//작곡가
    private String hasMusicVideoComposer = "http://iweb.yonsei.ac.kr/ontologies/smarttv/music/music_video__compositions";//작곡가2
    
    String revisedQuery = "";
    public ExtendedResources(Model model, OntologySearchbySPARQL oss) {
        this.tvModel = model;        
        this.oss = oss;
    }

    /**
     * 입력된 미디어의 타입에 따라 적합한 SPARQL을 활용하여 얻은 리소스 집합을 반환함
     *
     * @param media
     * @return
     */
    public Vector<Resource> getUserPreferedResources(Resource media) {
        Vector<Resource> resultSet = new Vector<Resource>();
        resultSet.add(media); // media도 선호 대상으로 추가
        NodeIterator ni = this.tvModel.listObjectsOfProperty(media, RDF.type);
//        Vector<SearchResultSet> result;
        Resource mediaType = null;
//        String revisedQuery = "";
        
        ArrayList<String> tvQueryList = new ArrayList<String>();
        tvQueryList.add(this.tvQueryGenre);
        tvQueryList.add(this.tvQueryTvActor);
        tvQueryList.add(this.tvQueryTvWriter);
        tvQueryList.add(this.tvQueryTvNetwork);
        
        ArrayList<String> filmQueryList = new ArrayList<String>();
        filmQueryList.add(filmQueryFilmGenre);
        filmQueryList.add(filmQueryFilmActor);
        filmQueryList.add(filmQueryFilmDirector);
        
        ArrayList<String> mvQueryList = new ArrayList<String>();
        mvQueryList.add(mvQueryArtist);
        mvQueryList.add(mvQueryComposer);
        
        while (ni.hasNext()) {
            mediaType = ni.nextNode().asResource();
            if (mediaType.getLocalName().equals("TvEpisode")) {
                resultSet = this.getResultSet(tvQueryList, media);
                break; // 타입이 여러개일 경우는 없음
            } else if (mediaType.getLocalName().equals("Film")) {
                resultSet = this.getResultSet(filmQueryList, media);
                break;
            } else if(mediaType.getLocalName().equals("MusicVideo")) {
                resultSet = this.getResultSet(mvQueryList, media);
                break;
            }
        }
        
        if(mediaType == null){
            return resultSet;            
        }else{
            resultSet.add(mediaType);
        }
        return resultSet;
    }
    private Vector<Resource> getResultSet(ArrayList<String> list, Resource media){
        Vector<Resource> resultSet = new Vector<Resource>();
        Vector<SearchResultSet> result ;
        for (int i = 0; i < list.size(); i++) {
            revisedQuery = list.get(i).replaceAll("media", media.toString());
            result = this.getExtenedResources(revisedQuery);

            for (int j = 0; j < result.size(); j++) {
                resultSet.add(result.get(j).getResult().getResultNode());
            }
        }
        return resultSet ; 
    }
    private Vector<SearchResultSet> getExtenedResources(String query) {
        Query tQuery = null;
        Vector<SearchResultSet> resultSet;
        try{
            tQuery = QueryFactory.create(query);            
            resultSet = this.oss.getSPARQLResult(tQuery);
            return resultSet;
        }catch(Exception e){            
//            System.out.println("Query is incorrect");
            return new Vector<SearchResultSet>();
        }
        
    }
}
